#include "PDI_2009_1.h"

enum { wxID_OPEN_WM, ID_RUN, ID_RUN_WM, ID_LINEAR, ID_WONG, ID_METODO2 };

#include <iostream>
using namespace std;

BEGIN_EVENT_TABLE ( MyFrame1, wxFrame )
   EVT_MENU ( wxID_ABOUT , MyFrame1::OnAbout )
   EVT_MENU ( wxID_OPEN , MyFrame1::OnOpen )
   EVT_MENU ( wxID_OPEN_WM , MyFrame1::OnOpenWatermark )
   EVT_MENU ( wxID_SAVE, MyFrame1::OnSave )
   EVT_MENU ( ID_RUN, MyFrame1::OnRun )
   EVT_MENU ( ID_RUN_WM, MyFrame1::OnRunWatermark )
   EVT_MENU ( wxID_EXIT, MyFrame1::OnQuit )
END_EVENT_TABLE ( )

void MyFrame1::OnAbout( wxCommandEvent& event )
{
   wxString msg;
   
   msg.Printf ( wxT ( "Testing About Dialog" ) );
   
   wxMessageBox ( msg, wxT ( "About This Program" ), wxOK | wxICON_INFORMATION, this );
}

void MyFrame1::OnOpen( wxCommandEvent& event )
{
   wxString caption = _T( "Choose an image" );
   wxString wildcard = _T( "JPEG files (*.jpg;*.JPG)|*.jpg;*.JPG" );
   wxString defaultDir = _T( "." );
   wxString defaultFileName = wxEmptyString;
      
   wxFileDialog dialog ( this, caption, defaultDir, defaultFileName, wildcard, wxFD_OPEN );
   
	if ( dialog.ShowModal ( ) == wxID_OK )
   {
      wxString path = dialog.GetPath();
     
      this->image1 = wxImage ( _T ( path ), wxBITMAP_TYPE_JPEG );
      if ( this->image1.IsOk(  ) )
      {
         wxBitmap openedImage = wxBitmap ( this->image1 );
         
         // se tiver alguma imagem no painel, apague-a
         if (m_panel1->GetSizer()->GetItem((size_t)0))
         {
         	wxWindow *w = m_panel1->GetSizer()->GetItem((size_t)0)->GetWindow();
            m_panel1->GetSizer()->Detach(w);
            m_panel1->GetSizer()->Remove(0);
            m_panel1->GetSizer()->Layout();
            m_panel1->Fit();          
         }
         
         // adicionando a imagem ao painel
         wxStaticBitmap *btmp = new wxStaticBitmap ( m_panel1, wxID_ANY, openedImage );
         m_panel1->GetSizer()->Add(btmp, 1, wxSHAPED, 0);
         
         m_panel1->Fit();
         this->Fit();
         
         this->Update();
      }
   }
}

void MyFrame1::OnOpenWatermark( wxCommandEvent& event )
{
   wxString caption = _T( "Choose an image" );
   wxString wildcard = _T( "JPEG files (*.jpg;*.JPG)|*.jpg;*.JPG" );
   wxString defaultDir = _T( "." );
   wxString defaultFileName = wxEmptyString;
      
   wxFileDialog dialog ( this, caption, defaultDir, defaultFileName, wildcard, wxFD_OPEN );
   
	if ( dialog.ShowModal ( ) == wxID_OK )
   {
      wxString path = dialog.GetPath();
     
      this->image2 = wxImage ( _T ( path ), wxBITMAP_TYPE_JPEG );
      if ( this->image2.IsOk(  ) )
      {
         wxBitmap openedImage = wxBitmap ( this->image2 );
         
         // se tiver alguma imagem no painel, apague-a
         if (m_panel2->GetSizer()->GetItem((size_t)0))
         {
         	wxWindow *w = m_panel2->GetSizer()->GetItem((size_t)0)->GetWindow();
            m_panel2->GetSizer()->Detach(w);
            m_panel2->GetSizer()->Remove(0);
            m_panel2->GetSizer()->Layout();
            m_panel2->Fit();          
         }
         
         // adicionando a imagem ao painel
         wxStaticBitmap *btmp = new wxStaticBitmap ( m_panel2, wxID_ANY, openedImage );
         m_panel2->GetSizer()->Add(btmp, 1, wxSHAPED, 0);
         
         m_panel2->Fit();
         this->Fit();
         
         this->Update();
      }
   }
}

void MyFrame1::OnSave( wxCommandEvent& event )
{
	if ( this->image3.IsOk( ) )
	{
		wxFileDialog dialog( this, "Choose a file", ".", "", "JPEG files (*.jpg)|*.jpg", wxFD_SAVE , wxDefaultPosition,wxDefaultSize, "Save image");
	
		if ( dialog.ShowModal ( ) == wxID_OK )
		{
			this->image3.SaveFile( wxT(dialog.GetPath ( ) + wxT(".jpg")), wxBITMAP_TYPE_JPEG );
		}
	}
	else
	{
		wxString msg;
		msg.Printf( wxT(" There is no image to save ") );
		wxMessageBox ( msg, wxT ( "Saving Error" ), wxOK | wxICON_ERROR, this );
	}
}

void MyFrame1::OnRun( wxCommandEvent& event )
{
	if ( this->image1.IsOk( ) && this->image2.IsOk( ) )
	{

		int min_x = ( this->image1.GetWidth() < this->image2.GetWidth()) ? this->image1.GetWidth() : this->image2.GetWidth();
		int min_y = ( this->image1.GetHeight() < this->image2.GetHeight()) ? this->image1.GetHeight() : this->image2.GetHeight();
	
		this->image3 = wxImage( min_x, min_y );
	
		for ( int x = 0; x < min_x; ++x )
			for ( int y = 0; y < min_y; ++y )
			{
				this->image3.SetRGB( x, y, abs(this->image1.GetRed(x,y) - this->image2.GetRed(x,y)),
													abs(this->image1.GetGreen(x,y) - this->image2.GetGreen(x,y)),
													abs(this->image1.GetBlue(x,y) - this->image2.GetBlue(x,y)) );
			}
	
		if (m_panel3->GetSizer()->GetItem((size_t)0))
		{
			wxWindow *w = m_panel3->GetSizer()->GetItem((size_t)0)->GetWindow();
		   m_panel3->GetSizer()->Detach(w);
		   m_panel3->GetSizer()->Remove(0);
		   m_panel3->GetSizer()->Layout();
		   m_panel3->Fit();          
		}
		
		wxStaticBitmap *btmp = new wxStaticBitmap ( m_panel3, wxID_ANY, this->image3 );
		m_panel3->GetSizer()->Add(btmp, 1, wxSHAPED, 0);
		
		m_panel3->Fit();
		this->Fit();
		
		this->Update();
	}
	else
	{
		wxString msg;
		msg.Printf( wxT(" There is no enougth images to do this operation ") );
		wxMessageBox ( msg, wxT ( "Could Not Open File" ), wxOK | wxICON_ERROR, this );
	}

}

void MyFrame1::OnRunWatermark( wxCommandEvent& event )
{
	if ( this->image1.IsOk( ) && this->image2.IsOk() )
	{
		if ( this->linear->IsChecked( ) )
		{
			this->RunLinear(0.5);
		}
		else
		if ( this->wong->IsChecked( ) )
		{
			wxString title;
			title.Printf("Wong Watermarking");
			this->RunWong(title);
		}
		else
		if ( this->metodo2->IsChecked( ) )
		{
			wxString title;
			title.Printf("Metodo2 Watermarking");
			this->RunMetodo2(title);	
		}
	}
	else
	{
		wxString msg;
		msg.Printf( wxT( "It is not possible to complete this operation!\nPlease open an image and a watermark." ) );
		wxMessageBox( msg, wxT("Insert Watermark ERROR"), wxOK | wxICON_ERROR, this );
	}
}

void MyFrame1::RunLinear ( float alfa )
{
	Watermark linearWM ( this->image1, this->image2 );
	linearWM.LinearCombination( alfa );
}

void MyFrame1::RunWong ( wxString title )
{
	Watermark wongWM ( this->image1, this->image2 );
	wongWM.wong( title );
}

void MyFrame1::RunMetodo2 ( wxString title )
{
	Watermark metodo2WM ( this->image1, this->image2 );
	metodo2WM.metodo2( title );
}


void MyFrame1::OnQuit( wxCommandEvent& event )
{
   Close ( );
}

MyFrame1::MyFrame1( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxFrame( parent, id, title, pos, size, style, name )
{
	wxInitAllImageHandlers();
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	
	menuBar = new wxMenuBar( 0 );
	menuFile = new wxMenu();
	wxMenuItem* openFile;
	openFile = new wxMenuItem( menuFile, wxID_OPEN, wxString( wxT("&Open") ) + wxT('\t') + wxT("Ctrl-O"), wxEmptyString, wxITEM_NORMAL );
	menuFile->Append( openFile );
		
	wxMenuItem* openMark;
	openMark = new wxMenuItem( menuFile, wxID_OPEN_WM, wxString( wxT("Open &Watermark") ) + wxT('\t') + wxT("Ctrl-Shift-O"), wxEmptyString, wxITEM_NORMAL );
	openMark->SetBitmap( wxBitmap( wxT("/usr/share/icons/gnome/16x16/actions/document-open.png") ) );
	menuFile->Append( openMark );
	
	wxMenuItem* saveFile;
	saveFile = new wxMenuItem( menuFile, wxID_SAVE, wxString( wxT("&Save") ) + wxT('\t') + wxT("Ctrl-S"), wxEmptyString, wxITEM_NORMAL );
	menuFile->Append( saveFile );
	
	wxMenuItem* exit;
	exit = new wxMenuItem( menuFile, wxID_EXIT, wxString( wxT("E&xit") ) + wxT('\t') + wxT("Alt-X"), wxEmptyString, wxITEM_NORMAL );
	menuFile->Append( exit );
	
	menuBar->Append( menuFile, wxT("&File") );
	
	waterMarkMenu = new wxMenu();
	fragileMenu = new wxMenu();
	waterMarkMenu->Append( -1, wxT("FragileMenu"), fragileMenu );
	
	// Anexar os metodos frageis no menu fragile ================================
	this->linear = new wxMenuItem  ( fragileMenu, ID_LINEAR, wxT("&Linear Combination"), wxEmptyString, wxITEM_RADIO );
	fragileMenu->Append (linear);

	this->wong = new wxMenuItem ( fragileMenu, ID_WONG, wxT("&Wong"), wxEmptyString, wxITEM_RADIO );
	fragileMenu->Append (wong);
	
	this->metodo2 = new wxMenuItem ( fragileMenu, ID_METODO2, wxT("&Metodo 2"), wxEmptyString, wxITEM_RADIO );
	fragileMenu->Append (metodo2);
	// Fim dos metodos frageis ==================================================
		
	menuBar->Append( waterMarkMenu, wxT("Watermark") );
	
	helpMenu = new wxMenu();
	menuBar->Append( helpMenu, wxT("&Help") );
	
	wxMenuItem* about;
	about = new wxMenuItem( helpMenu, wxID_ABOUT, wxT("&About"), wxEmptyString, wxITEM_NORMAL );
	helpMenu->Append( about );
	
	this->SetMenuBar( menuBar );
	
	mytoolbar = this->CreateToolBar( wxTB_HORIZONTAL, wxID_ANY ); 
	mytoolbar->AddTool( wxID_OPEN, wxT("Open"), wxBitmap( wxT("/usr/share/icons/gnome/32x32/actions/document-open.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Open an Image (Ctrl+O)"), wxEmptyString );
	mytoolbar->AddTool( wxID_OPEN_WM, wxT("Open Water Mark Image"), wxBitmap( wxT("/usr/share/icons/gnome/32x32/actions/gtk-paste.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Open WaterMark Image"), wxEmptyString );
	mytoolbar->AddTool( wxID_SAVE, wxT("Save"), wxBitmap( wxT("/usr/share/icons/gnome/32x32/actions/document-save.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Save Result Image (Ctrl+S)"), wxEmptyString );
	mytoolbar->AddSeparator();
	mytoolbar->AddTool( ID_RUN, wxT("Run"), wxBitmap( wxT("/usr/share/icons/gnome/32x32/actions/gtk-execute.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Run Difference"), wxEmptyString );
	mytoolbar->AddTool( ID_RUN_WM, wxT("Add Watermark"), wxBitmap( wxT("/usr/share/icons/gnome/32x32/actions/insert-image.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Add Watermark"), wxEmptyString );
	mytoolbar->Realize();
	
	m_statusBar1 = this->CreateStatusBar( 2, wxST_SIZEGRIP, wxID_ANY );
	wxGridSizer* gSizer1;
	gSizer1 = new wxGridSizer( 2, 3, 0, 0 );
	
	m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	gSizer1->Add( m_panel1, 1, wxEXPAND|wxALL, 5 );
	wxBoxSizer *pnlSizer1 = new wxBoxSizer ( wxHORIZONTAL );
   m_panel1->SetSizer ( pnlSizer1 );
	
	m_panel2 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	gSizer1->Add( m_panel2, 1, wxEXPAND | wxALL, 5 );
	wxBoxSizer *pnlSizer2 = new wxBoxSizer ( wxHORIZONTAL );
   m_panel2->SetSizer ( pnlSizer2 );
	
	m_panel3 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	gSizer1->Add( m_panel3, 1, wxEXPAND | wxALL, 5 );
	wxBoxSizer *pnlSizer3 = new wxBoxSizer ( wxHORIZONTAL );
   m_panel3->SetSizer ( pnlSizer3 );
	
	this->SetSizer( gSizer1 );
	this->Layout();
}

MyFrame1::~MyFrame1()
{
}
